﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="CommonSliderPanel.cs" company="BerlinSoft">
//   Wernfried Schwenkner
// </copyright>
// <summary>
//   Defines the MenuEnty type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using SenseTimeTracker.BusinessLayer;
using SenseTimeTracker.Misc;
using SenseTimeTracker.Properties;
using StedySoft.SenseSDK;

namespace SenseTimeTracker.Main
{
	/// <summary>
	/// Enumeration of available standard menu items
	/// </summary>
	[Flags]
	public enum MenuEnty
	{
		/// <summary>
		/// Menu item for creating new entries
		/// </summary>
		New = 0x0001,

		/// <summary>
		/// Menu item for editing entries
		/// </summary>
		Edit = 0x0002,

		/// <summary>
		/// Menu item for removing entries
		/// </summary>
		Remove = 0x0004,

		/// <summary>
		/// Menu item for copying entried
		/// </summary>
		Copy = 0x0008,

		/// <summary>
		/// Menu item for duplicating entries
		/// </summary>
		Duplicate = 0x0010,

		/// <summary>
		/// Synonym for all menu entries
		/// </summary>
		All = 0x001f,
	}

	public abstract class CommonSliderPanel<T> : SliderPanel where T : IColumnSortable
	{
		protected SensePanelMoreItem filterItem;
		protected Persistance.Sorting sorting;
		protected SortColumn sortColumns;

		private static SensePanelComboItem sortColumnComboBox;
		private static SensePanelComboItem sortOrderComboBox;
		private static SenseListControl theSenseListControl;
		private static Persistance.Sorting theSorting;

		private CommonMenuItem menuItemNewEntry;
		private CommonMenuItem menuItemEditEntry;
		private CommonMenuItem menuItemRemoveEntry;
		private CommonMenuItem menuItemCopyEntry;
		private CommonMenuItem menuItemDuplicateEntry;

		private CommonMenuItem contextMenuItemNewEntry;
		private CommonMenuItem contextMenuItemEditEntry;
		private CommonMenuItem contextMenuItemCopyEntry;
		private CommonMenuItem contextMenuItemDuplicateEntry;
		private CommonMenuItem contextMenuItemRemoveEntry;

		static CommonSliderPanel()
		{
			sortColumnComboBox = new SensePanelComboItem();
			sortColumnComboBox.LabelText = string.Format("{0}:", Resources.SortedByLabel);
			sortColumnComboBox.ShowSeparator = true;
			sortColumnComboBox.OnSelectedValueChanged += sortColumnComboBox_OnSelectedValueChanged;

			sortOrderComboBox = new SensePanelComboItem();
			sortOrderComboBox.LabelText = string.Format("{0}:", Resources.SortOrderLabel);
			sortOrderComboBox.ShowSeparator = true;
			foreach (KeyValuePair<object, string> sortOrder in EnumExtension.GetValues(typeof(SortOrder)))
			{
				sortOrderComboBox.Items.Add(new SensePanelComboItem.Item(sortOrder.Value, sortOrder.Key));
			}

			sortOrderComboBox.OnSelectedValueChanged += sortOrderComboBox_OnSelectedValueChanged;
		}

		static void sortColumnComboBox_OnSelectedValueChanged(object Sender, object Value)
		{
			theSorting.Column = (SortColumn)Value;
			Persistance.Instance.Serialize();
		}

		static void sortOrderComboBox_OnSelectedValueChanged(object Sender, object Value)
		{
			theSorting.Order = (SortOrder)Value;
			Persistance.Instance.Serialize();
			sortColumnComboBox.Enabled = (SortOrder)Value != SortOrder.Unsorted;
			theSenseListControl.Invalidate();
		}

		public CommonSliderPanel(SenseTimeTrackerForm form, string smallIconName, string largeIconName, MenuEnty menuEntry)
			: base(form, smallIconName, largeIconName)
		{
			menuItem = new MenuItem();
			menuItem.Text = Resources.MenuItemMenu;
			contextMenu = new ContextMenu();

			if ((menuEntry & MenuEnty.New) != 0)
			{
				menuItemNewEntry = new CommonMenuItem();
				menuItemNewEntry.Text = Resources.MenuItemNew;
				menuItemNewEntry.ContextSensitive = false;
				menuItemNewEntry.Click += MenuItemNewEntry_Click;
				menuItem.MenuItems.Add(menuItemNewEntry);

				contextMenuItemNewEntry = new CommonMenuItem();
				contextMenuItemNewEntry.Text = Resources.MenuItemNew;
				contextMenuItemNewEntry.ContextSensitive = false;
				contextMenuItemNewEntry.Click += MenuItemNewEntry_Click;
				contextMenu.MenuItems.Add(contextMenuItemNewEntry);
			}

			if ((menuEntry & MenuEnty.Edit) != 0)
			{
				menuItemEditEntry = new CommonMenuItem();
				menuItemEditEntry.Text = Resources.MenuItemEdit;
				menuItemEditEntry.Click += MenuItemEditEntry_Click;
				menuItem.MenuItems.Add(menuItemEditEntry);

				contextMenuItemEditEntry = new CommonMenuItem();
				contextMenuItemEditEntry.Text = Resources.MenuItemEdit;
				contextMenuItemEditEntry.Click += MenuItemEditEntry_Click;
				contextMenu.MenuItems.Add(contextMenuItemEditEntry);
			}

			if ((menuEntry & MenuEnty.Copy) != 0)
			{
				menuItemCopyEntry = new CommonMenuItem();
				menuItemCopyEntry.Text = Resources.MenuItemCopy;
				menuItemCopyEntry.Click += MenuItemCopyEntry_Click;
				menuItem.MenuItems.Add(menuItemCopyEntry);

				contextMenuItemCopyEntry = new CommonMenuItem();
				contextMenuItemCopyEntry.Text = Resources.MenuItemCopy;
				contextMenuItemCopyEntry.Click += MenuItemCopyEntry_Click;
				contextMenu.MenuItems.Add(contextMenuItemCopyEntry);
			}

			if ((menuEntry & MenuEnty.Duplicate) != 0)
			{
				menuItemDuplicateEntry = new CommonMenuItem();
				menuItemDuplicateEntry.Text = Resources.MenuItemDuplicate;
				menuItemDuplicateEntry.Click += MenuItemDuplicateEntry_Click;
				menuItem.MenuItems.Add(menuItemDuplicateEntry);

				contextMenuItemDuplicateEntry = new CommonMenuItem();
				contextMenuItemDuplicateEntry.Text = Resources.MenuItemDuplicate;
				contextMenuItemDuplicateEntry.Click += MenuItemDuplicateEntry_Click;
				contextMenu.MenuItems.Add(contextMenuItemDuplicateEntry);
			}

			if ((menuEntry & MenuEnty.Remove) != 0)
			{
				menuItemRemoveEntry = new CommonMenuItem();
				menuItemRemoveEntry.Text = Resources.MenuItemRemove;
				menuItemRemoveEntry.Click += MenuItemRemoveEntry_Click;
				menuItem.MenuItems.Add(menuItemRemoveEntry);

				contextMenuItemRemoveEntry = new CommonMenuItem();
				contextMenuItemRemoveEntry.Text = Resources.MenuItemRemove;
				contextMenuItemRemoveEntry.Click += MenuItemRemoveEntry_Click;
				contextMenu.MenuItems.Add(contextMenuItemRemoveEntry);
			}
		}

		public override void Bind(SenseListControl senseListControl)
		{
			base.Bind(senseListControl);

			filterItem = new SensePanelMoreItem();
			filterItem.ShowSeparator = true;
			senseListControl.AddItem(filterItem);
		}

		public void BindFilter(SenseListControl.ISenseListItem[] items, string header)
		{
			base.BindFilter();

			theSenseListControl = senseListControl;
			theSorting = sorting;

			sortColumnComboBox.Items.Clear();
			sortColumnComboBox.Enabled = sorting.Order != SortOrder.Unsorted;

			foreach (KeyValuePair<object, string> sortColumn in EnumExtension.GetValues(typeof(SortColumn)))
			{
				if ((((int)sortColumn.Key) & (int)sortColumns) != 0)
				{
					sortColumnComboBox.Items.Add(new SensePanelComboItem.Item(sortColumn.Value, sortColumn.Key));
				}
			}

			sortColumnComboBox.SelectedValue = sorting.Column;
			sortOrderComboBox.SelectedValue = sorting.Order;

			senseListControl.Clear();
			senseListControl.AddItem(new SensePanelDividerItem(string.Empty, header));
			foreach (SenseListControl.ISenseListItem item in items)
			{
				senseListControl.AddItem(item);
			}

			senseListControl.AddItem(sortColumnComboBox);
			senseListControl.AddItem(sortOrderComboBox);
		}

		protected void SortFilter(ref IEnumerable<T> collection)
		{
			foreach (KeyValuePair<object, string> sortColumn in EnumExtension.GetValues(typeof(SortColumn)))
			{
				if ((SortColumn)sortColumn.Key == sorting.Column)
				{
					switch (sorting.Order)
					{
						case SortOrder.Ascending:
							collection = from filter in collection orderby SortColumnValue(filter, (SortColumn)sortColumn.Key) ascending select filter;
							filterItem.SecondaryText = string.Format(Resources.SortedByAscending, sortColumn.Value);
							break;
						case SortOrder.Descending:
							collection = from filter in collection orderby SortColumnValue(filter, (SortColumn)sortColumn.Key) descending select filter;
							filterItem.SecondaryText = string.Format(Resources.SortedByDescending, sortColumn.Value);
							break;
						case SortOrder.Unsorted:
							filterItem.SecondaryText = Resources.SortedByUnsorted;
							break;
					}

					break;
				}
			}
		}

		private object SortColumnValue(IColumnSortable sortableColumn, SortColumn sortColumn)
		{
			switch (sortColumn)
			{
				case SortColumn.Name:
					return sortableColumn.Name;
				case SortColumn.Type:
					return sortableColumn.Type;
				case SortColumn.Number:
					return sortableColumn.Number;
				case SortColumn.Description:
					return sortableColumn.Description;
				case SortColumn.Date:
					return sortableColumn.Date;
				case SortColumn.Duration:
					return sortableColumn.Duration;
				default:
					throw new NotSupportedException();
			}
		}

		public void BindFilter(SenseListControl.ISenseListItem item, string header)
		{
			BindFilter(new[] { item }, header);
		}

		public void BindFilter(string header)
		{
			BindFilter(new SenseListControl.ISenseListItem[0], header);
		}

		protected virtual void MenuItemNewEntry_Click(object sender, EventArgs e)
		{
		}

		protected virtual void MenuItemEditEntry_Click(object sender, EventArgs e)
		{
		}

		protected virtual void MenuItemRemoveEntry_Click(object sender, EventArgs e)
		{
		}

		protected virtual void MenuItemCopyEntry_Click(object sender, EventArgs e)
		{
		}

		protected virtual void MenuItemDuplicateEntry_Click(object sender, EventArgs e)
		{
		}
	}
}
